package main

import (
	"fmt"
	"image"
	"image/draw"
	"io/ioutil"
	"os"
	"strconv"
	"errors"
)

// a Plan 9 image, known to the draw device
type Image struct {
	image.RGBA
	id int	// the id registered to the draw device
}

// represents a connection to the draw device
var display struct {
	n       int
	id      int
	chanfmt string
	drect   image.Rectangle
	crect   image.Rectangle
}

// the window
var screen draw.Image

// details in draw(3)
type ctlfields struct {
	n       int
	id      int
	chanfmt string
	drect   image.Rectangle
	crect   image.Rectangle
}

var window int
var screenRect image.Rectangle
var white, black int

func getfields(f *os.File) *ctlfields {
	buf := make([]byte, 12*12)
	n, err := f.Read(buf)
	if n != 144 || err != nil {
		fmt.Fprintln(os.Stderr, "error reading file", f, ":", err)
		fmt.Fprintln(os.Stderr, "read", n, "characters")
		return nil
	}
	fields := string(buf)

	var nconn, id, junk, dxmin, dymin, dxmax, dymax, cxmin, cymin, cxmax, cymax int
	var chanfmt string
	n, err = fmt.Sscanf(fields, "%d %d %s %d %d %d %d %d %d %d %d %d ",
		&nconn, &id, &chanfmt, &junk, &dxmin, &dymin, &dxmax, &dymax,
		&cxmin, &cymin, &cxmax, &cymax)
	if n != 12 || err != nil {
		fmt.Fprintln(os.Stderr, "error parsing connection details:", fields, ":", err)
		fmt.Fprintln(os.Stderr, "read", n, "fields")
		return nil
	}
	c := new(ctlfields)
	c.n = nconn
	c.id = id
	c.chanfmt = chanfmt
	c.drect = image.Rect(dxmin, dymin, dxmax, dymax)
	c.crect = image.Rect(cxmin, cymin, cxmax, cymax)
	return c
}

func Initdraw(label string) error {
	f, err := os.Open("/dev/draw/new")
	if err != nil {
		return errors.New("error opening a new connection: " + err.Error())
	}
	conn := getfields(f)
	//fmt.Println(conn.chanfmt)
	n := strconv.Itoa(conn.n)
	devdraw, err = os.OpenFile("/dev/draw/"+n+"/data", os.O_RDWR, 0)
	if err != nil {
		return errors.New("error opening data file: " + err.Error())
	}
	white, err = AllocImage(image.Rect(0, 0, 1, 1), 0, GREY1, 1, DWhite)
	if err != nil {
		return errors.New("error allocating image: " + err.Error())
	}
	black, err = AllocImage(image.Rect(0, 0, 1, 1), 0, GREY1, 1, DBlack)
	_ = black
	if err != nil {
		return errors.New("error allocating image: " + err.Error())
	}
	winname, err := ioutil.ReadFile("/dev/winname")
	if err != nil {
		return errors.New("error reading winname: " + err.Error())
	}
	winid, err := NamedImage(string(winname))
	if err != nil {
		return errors.New("error getting id for " +  string(winname) + ": " + err.Error())
	}
	AllocScreen(winid, white)

	ctl, err := os. Open("/dev/draw/"+n+"/ctl")
	if err != nil {
		return errors.New("error opening /dev/draw/"+n+"/ctl: " + err.Error())
	}
	screenInfo := getfields(ctl)
	screenRect = screenInfo.drect.Inset(Borderwidth)
	//fmt.Println("window size:", screenRect)

	window, err = AllocImage(screenRect, 1, XBGR32, 0, DWhite)
	if err != nil {
		return errors.New("error allocating image: " + err.Error())
	}
	return nil
}
